#ifndef FLOCKTEST_H
#define FLOCKTEST_H

#include <cstdlib>

#include <QObject>
#include <QSize>
#include <QTimer>
#include <QWidget>

#include "ai/flock.h"

class QPainter;
class QPaintEvent;
class QMouseEvent;
class QResizeEvent;

class FlockWidget : public QWidget
{
    Q_OBJECT

public:
    FlockWidget(QWidget* pkParent = NULL);
    ~FlockWidget();

    QSize minimumSizeHint() const;
    QSize sizeHint() const;

public slots:
    void setUpdateDelay(int msec);

    void reset();
    void setAgentCount(int iCount);

    void setBodiesVisible(bool bVisible);
    void setRangesVisible(bool bVisible);
    void setQuadtreeVisible(bool bVisible);

    void setRepulsionFactor(int iFactor);
    void setAlignementFactor(int iFactor);
    void setAttractionFactor(int iFactor);

    void setRepulsionFunction(int iFunctionIndex);
    void setAlignementFunction(int iFunctionIndex);
    void setAttractionFunction(int iFunctionIndex);

    void setDisturbance(int iDisturbanceIndex);
    void setDisturbanceFunction(int iFunctionIndex);
    void setDisturbanceFactor(int iFactor);
    void setDisturbance(const QVector3D& rkPosition);
    void setDisturbance(qreal x, qreal y, qreal z);

    void step();

protected:
    FlockWidget(const FlockWidget&);
    FlockWidget& operator = (const FlockWidget&);

    void mouseMoveEvent(QMouseEvent* pkEvent);

    void paintEvent(QPaintEvent* pkEvent);
    void resizeEvent(QResizeEvent* pkEvent);

private:
    void paintAgents(QPainter& rkPainter);
    void paintBodies(QPainter& rkPainter);
    void paintRanges(QPainter& rkPainter);
    void paintBodiesQuadtree(QPainter& rkPainter);
    void paintRangesQuadtree(QPainter& rkPainter);

    //---------------------------------------------------------------
    // Members.
    //---------------------------------------------------------------
    // Quadtree default spanning.
    static const quint8 s_uiSpanning = 200;

    // Default update delay.
    static const qreal  s_DefaultUpdateDelay = 1000. / 33.;

    // Flock & agents.
    Flock               m_kFlock;
    QSet< Agent* >      m_kAgents;

    // Update timer.
    QTimer              m_kTimer;

    // Toggles.
    bool                m_bBodiesVisible;
    bool                m_bRangesVisible;
    bool                m_bQuadtreeVisible;
};

#endif // FLOCKTEST_H
